package com.szwistar.common.os;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.URI;
import java.net.URL;
import java.net.URLDecoder;

public class PathUtils {
	/**
	 * 获取类所在的路径
	 * @param clazz 指定类
	 * @param subPath 相对于类所在路径的子路径
	 * @return <ul> 当 subPath 为 null 时：
	 *   <li>如果这个类是在 jar 包中，则返回 jar 包中路径，如: {@code getFile(CoManager.class, null)} 将返回 {@code C:\run\CloudGateway\gateway4.jar}
	 *   <li>如果是在 Eclipse 中调试，则可能返回编译出来的 class 文件所在的根路径：{@code C:\dev-work\EclipseWorkspace2\eHome-gateway4.0\Gateway-Core\bin}
	 * <ul>
	 */
	public static File getFile(Class<?> clazz, String subPath) throws Exception {
    	String clazzPath = clazz.getProtectionDomain().getCodeSource().getLocation().getPath();
    	clazzPath = URLDecoder.decode(clazzPath, "UTF-8");
		File file = (subPath == null) ? new File(clazzPath) : new File(clazzPath, subPath);
		return file.toPath().normalize().toFile();
	}

	/**
	 * 获取类所在的路径
	 * @param clazz 指定类
	 * @param subPath 相对于类所在路径的子路径
	 * @return <ul> 当 subPath 为 null 时：
	 *   <li>如果这个类是在 jar 包中，则返回 jar 包中路径，如: {@code getFile(CoManager.class, null)} 将返回 {@code C:\run\CloudGateway\gateway4.jar}
	 *   <li>如果是在 Eclipse 中调试，则可能返回编译出来的 class 文件所在的根路径：{@code C:\dev-work\EclipseWorkspace2\eHome-gateway4.0\Gateway-Core\bin}
	 * <ul>
	 */
	public static URL getUrl(Class<?> clazz, String subPath) throws Exception {
    	return getFile(clazz, subPath).toURI().toURL();
	}

	/**
	 * 获取文件的 URL
	 */
	public static String getUrl(String path) throws Exception {
		File file = new File(path);
		URI uri = file.toURI();
		return "file://" + uri.getPath();
	}

	/**
	 * 获取程序启动时所在的当前路径
	 */
	public static String getCurrentDir() {
		return System.getProperty("user.dir");
	}

	/**
	 * 获取路径中最后一个部分之前的部分
	 * 如：/a/b/c.txt --> /a/b/
	 */
	public static String getParent(String path) throws Exception {
		int pos = Math.max(path.lastIndexOf('/'), path.lastIndexOf('\\'));
    	return path.substring(0, pos+1);
	}

	/**
	 * 获取路径中的最后一个'/'后面的部分
	 * 如：/a/b/c.txt --> c.txt
	 * @param path
	 * @return
	 */
	public static String getTail(String path) {
		int pos = Math.max(path.lastIndexOf('/'), path.lastIndexOf('\\'));
    	return path.substring(pos+1);
	}

	/**
	 * 取路径中文件名的主文件名
	 * 如：/a/b/c.txt --> c
	 * @param path
	 * @return
	 */
	public static String getFileMainName(String path) {
		return getTail(getTrunk(path));
	}

	/**
	 * 获取路径中的文件扩展名
	 * 如：/a/b/c.txt --> txt
	 * @param path
	 * @return
	 */
	public static String getFileExtension(String path) {
		path = getTail(path);
		int pos = path.lastIndexOf(".");
		if(pos >= 0) {
			return path.substring(pos + 1);
		} else {
			return "";
		}
	}

	/**
	 * 取路径中除文件扩展名以外的部分
	 * 如：/a/b/c.txt --> /a/b/c
	 * @param path
	 * @return
	 */
	public static String getTrunk(String path) {
		return path.substring(0, path.lastIndexOf("."));
	}

	/**
	 * 拷贝文件
	 * @param src
	 * @param dst
	 * @throws IOException
	 */
	public static void copyFile(String src, String dst) throws IOException {
		copyFile(new File(src), new File(dst));
	}

	/**
	 * 拷贝文件
	 * @param src
	 * @param dst
	 * @throws IOException
	 */
	public static void copyFile(File src, File dst) throws IOException {
		if (dst.exists()) {
			dst.delete();
		}

		InputStream in = new FileInputStream(src);
		OutputStream out = new FileOutputStream(dst);

		byte[] buf = new byte[1024];
		int len;
		while ((len = in.read(buf)) > 0) {
			out.write(buf, 0, len);
		}

		in.close();
		out.close();
	}

	public static void dumpInfo() {
        System.out.println("java.home = " + System.getProperty("java.home"));
        System.out.println("java.class.version = " + System.getProperty("java.class.version"));
        System.out.println("java.class.path = " + System.getProperty("java.class.path"));
        System.out.println("java.library.path = " + System.getProperty("java.library.path"));
        System.out.println("java.io.tmpdir = " + System.getProperty("java.io.tmpdir"));
        System.out.println("java.compiler = " + System.getProperty("java.compiler"));
        System.out.println("java.ext.dirs = " + System.getProperty("java.ext.dirs"));
        System.out.println("user.name = " + System.getProperty("user.name"));
        System.out.println("user.home = " + System.getProperty("user.home"));
        System.out.println("user.dir = " + System.getProperty("user.dir"));
	}

    /**
     * 先根遍历序递归删除文件夹
     * @param dirFile 要被删除的文件或者目录
     * @return 删除成功返回true, 否则返回false
     */
    public static boolean deletePath(File dirFile) {
        // 如果dir对应的文件不存在，则退出
        if (!dirFile.exists()) { return false; }

        if (dirFile.isFile()) {
            return dirFile.delete();
        }
        for (File file : dirFile.listFiles()) {
            deletePath(file);
        }
        return dirFile.delete();
    }

    /**
     * 判断指定路径是否为目录且存在
     */
    public static boolean existDir(File path) {
    	return (path != null) && path.exists() && path.isDirectory();
    }

    /**
     * 判断指定路径是否为目录且存在
     */
    public static boolean existDirs(File ...paths) {
    	if(paths.length < 1) { return false; }
    	for(File path: paths) {
    		if(!existDir(path)) { return false; }
    	}
    	return true;
    }

    /**
     * 判断指定路径是否为文件且存在
     */
    public static boolean existFile(File path) {
    	return (path != null) && path.exists() && path.isFile();
    }

    /**
     * 判断指定路径是否为文件且存在
     */
    public static boolean existFiles(File ...paths) {
    	if(paths.length < 1) { return false; }
    	for(File path: paths) {
    		if(!existFile(path)) { return false; }
    	}
    	return true;
    }

	public static void main(String[] args) throws Exception {
		String path = null;
		path = getParent("/a/b/c.txt");
		System.out.println(path);
		path = getTail("/a/b/c.txt");
		System.out.println(path);
	}
}
